package com.csstu.tomcat;

import com.csstu.tomcat.handler.CsRequestHandler;
import com.csstu.tomcat.servlet.CsHttpServlet;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @program: cstomcat
 * @description: 手写的tomcat v1版本
 * @author: 程硕
 * @create: 2025-08-16 20:35
 * @version: 3.0 实现通过xml + 反射初始化容器
 **/
public class CsTomcat {
    public static final ConcurrentHashMap<String, CsHttpServlet>
            servletMapping = new ConcurrentHashMap<>();
    public static final ConcurrentHashMap<String, String>
            servletUrlMapping = new ConcurrentHashMap<>();
    public static void main(String[] args) {
        CsTomcat csTomcat = new CsTomcat();
        csTomcat.init();
        csTomcat.start();
    }
    // 启动tomcat容器
    public void start(){
        try {
            ServerSocket serverSocket = new ServerSocket(9090);
            System.out.println("服务器启动成功 port:9090");
            while (!serverSocket.isClosed()){
                Socket socket = serverSocket.accept();
                Thread thread = new Thread(new CsRequestHandler(socket));
                thread.start();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
    //直接对两个容器进行初始化
    public void init(){
        //读取web.xml => dom4j =>
        //得到web.xml文件的路径
        String path = CsTomcat.class.getResource("/").getPath();
        SAXReader saxReader = new SAXReader();

        try {
            Document document = saxReader.read(new File(path + "web.xml"));
            System.out.println("document= " + document);
            Element rootElement = document.getRootElement();

            List<Element> elements = rootElement.elements();
            //遍历并过滤servlet servlet-mapping
            for (Element element : elements) {
                if ("servlet".equalsIgnoreCase(element.getName())){
                    //这是以一个servlet配置
                    System.out.println("发现 servlet");
                    //使用反射将该servlet实例放到容器中
                    Element servletName = element.element("servlet-name");
                    Element servletClass = element.element("servlet-class");
                    servletMapping.put(servletName.getText(),
                            (CsHttpServlet) Class.forName(servletClass.getText().trim()).newInstance() );
                }else if ("servlet-mapping".equalsIgnoreCase(element.getName())){
                    System.out.println("发现 servlet-mapping");
                    Element servletName = element.element("servlet-name");
                    Element urlPatter = element.element("url-pattern");
                    servletUrlMapping.put(urlPatter.getText(), servletName.getText());
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        System.out.println("初始化容器完成");
        System.out.println("servletMapping= " + servletMapping);
        System.out.println("servletUrlMapping= " + servletUrlMapping);
    }

}
